﻿using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace BLL
{
    /// <summary>
    /// 加密工具类
    /// </summary>
    public class Security
    {
        /// <summary>  
        /// 加密  
        /// </summary>  
        /// <param name="source">数据</param>  
        /// <param name="_KEY">解密序列码，必须为8个以“-”间隔的三位数数字编码，“xxx-xxx-xxx-xxx-xxx-xxx-xxx-xxx” 种格式</param>  
        /// <returns></returns>  
        public static string DES_Encode(string source, string _KEY)
        {
            if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(_KEY))
            {
                _KEY = GetCode(_KEY);

                byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(_KEY.Split('$')[0]);
                byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(_KEY.Split('$')[1]);

                DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
                int i = cryptoProvider.KeySize;
                MemoryStream ms = new MemoryStream();
                CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

                StreamWriter sw = new StreamWriter(cst);
                sw.Write(source);
                sw.Flush();
                cst.FlushFinalBlock();
                sw.Flush();

                string strRet = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
                return strRet;
            }
            else
            {
                return "";
            }
        }

        /// <summary>  
        /// 解密  
        /// </summary>  
        /// <param name="data">数据</param>  
        /// <param name="_KEY">解密序列码，必须为8个以“-”间隔的三位数数字编码，“xxx-xxx-xxx-xxx-xxx-xxx-xxx-xxx” 种格式</param>  
        /// <returns></returns>  
        public static string DES_Decode(string source, string _KEY)
        {
            if (!string.IsNullOrEmpty(source) && !string.IsNullOrEmpty(_KEY))
            {
                _KEY = GetCode(_KEY);

                byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(_KEY.Split('$')[0]);
                byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(_KEY.Split('$')[1]);

                byte[] byEnc;

                try
                {
                    source.Replace("_%_", "/");
                    source.Replace("-%-", "#");
                    byEnc = Convert.FromBase64String(source);

                }
                catch
                {
                    return null;
                }

                DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
                MemoryStream ms = new MemoryStream(byEnc);
                CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
                StreamReader sr = new StreamReader(cst);
                return sr.ReadToEnd();
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// Md5加密
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string MD5(string source)
        {
            if (!string.IsNullOrEmpty(source))
            {
                MD5 getmd5 = new MD5CryptoServiceProvider();
                byte[] targetStr = getmd5.ComputeHash(UnicodeEncoding.UTF8.GetBytes(source));
                return BitConverter.ToString(targetStr).Replace("-", "");
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string MD5_Dode(string password)
        {
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(password, "MD5").ToUpper();
        }
        /// <summary> 
        /// MD5解密
        /// </summary>
        /// <param name="sqlPwd">加密在在数据库的密码</param>
        /// <param name="inputPwd">输入的登陆密码</param>
        /// <returns>相同true，否则false</returns>
        public static Boolean MD5_Decode(string sqlPwd,string inputPwd)
        {
            string strPwd = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sqlPwd, "MD5");
            string pwds = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(inputPwd, "MD5");
            if(strPwd==pwds)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 根据解密参数序列得到解密密钥
        /// </summary>
        /// <param name="Key">解密参数序列</param>
        /// <returns></returns>
        private static string GetCode(string Key)
        {
            StringBuilder sbrK = new StringBuilder();
            sbrK.Append("9,C,E,y,Y,m,n,Y,o,X,a,M,c,S,d,5,e,i,8,j,Q,k,F,l,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,");
            sbrK.Append("A,4,u,6,t,7,v,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,S,d,5,e,C,E,b,G,w,H,h,I,D,2,A,4,d,5,e,i,X,u,6,t,7,v,9,C,E,b,");
            sbrK.Append("M,c,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,O,s,P,3,0,T,f,U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,X,a,o,V,p,B,q,r,R,x,z,1,D,2,");
            sbrK.Append("A,4,u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,s,P,3,0,T,f,U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,");
            sbrK.Append("F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,S,d,5,e,i,X,9,C,E,y,Y,");
            sbrK.Append("9,C,E,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,S,d,5,e,i,X,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,");
            sbrK.Append("a,M,c,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,");
            sbrK.Append("s,P,3,0,T,f,U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,X,a,M,c,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,");
            sbrK.Append("U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,X,a,M,c,S,d,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,5,e,i,8,j,Q,k,F,l,m,n,s,P,3,0,T,f,");
            sbrK.Append("u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,s,P,3,0,T,f,U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,9,C,E,y,Y,");
            sbrK.Append("m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,S,d,5,e,i,X,a,M,");
            sbrK.Append("c,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,s,P,");
            sbrK.Append("3,0,T,f,U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,X,a,M,c,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,");
            sbrK.Append("f,U,g,9,C,E,y,Y,W,Z,M,W,4,x,Q,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,s,P,3,0,T,");
            sbrK.Append("m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,S,d,5,e,i,X,a,M,c,");
            sbrK.Append("S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,s,P,3,0,");
            sbrK.Append("T,f,U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,X,a,M,c,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,");
            sbrK.Append("7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,s,P,3,0,T,f,U,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,");
            sbrK.Append("p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,S,d,5,e,i,X,a,M,c,S,d,5,e,i,8,");
            sbrK.Append("j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,b,G,w,H,h,I,J,K,L,N,O,s,P,3,0,T,f,U,g,W,Z,M,W,");
            sbrK.Append("4,x,Q,y,Y,z,9,B,X,a,M,c,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2,A,4,u,6,t,7,v,9,C,E,b,G,w,H,");
            sbrK.Append("h,I,J,K,L,N,O,s,P,3,0,T,f,U,9,C,E,y,Y,g,W,Z,M,W,4,x,Q,y,Y,z,9,B,S,d,5,e,i,8,j,Q,k,F,l,m,n,Y,o,V,p,B,q,r,R,x,z,1,D,2");
 
            string[] k1 = sbrK.ToString().Split(',');
            string[] k2 = Key.Split('-');

            try
            {
                Key = k1[Convert.ToInt32(k2[0])];
                Key += k1[Convert.ToInt32(k2[1])];
                Key += k1[Convert.ToInt32(k2[2])];
                Key += k1[Convert.ToInt32(k2[3])];
                Key += k1[Convert.ToInt32(k2[4])];
                Key += k1[Convert.ToInt32(k2[5])];
                Key += k1[Convert.ToInt32(k2[6])];
                Key += k1[Convert.ToInt32(k2[7])];

                Key += "$";

                Key += k1[Convert.ToInt32(k2[7])];
                Key += k1[Convert.ToInt32(k2[6])];
                Key += k1[Convert.ToInt32(k2[5])];
                Key += k1[Convert.ToInt32(k2[4])];
                Key += k1[Convert.ToInt32(k2[3])];
                Key += k1[Convert.ToInt32(k2[2])];
                Key += k1[Convert.ToInt32(k2[1])];
                Key += k1[Convert.ToInt32(k2[0])];

                return Key;
            }
            catch
            {
                throw new Exception("解密序列码不正确，必须为8个以“-”间隔的三位数数字编码，“xxx-xxx-xxx-xxx-xxx-xxx-xxx-xxx” 种格式");
            }
        }

        /// <summary>
        /// 自动生成加密密钥序列
        /// </summary>
        /// <returns></returns>
        public static string DES_GetKey()
        {
            string K = "";
            Random rdm = new Random();

            for (int i = 0; i < 8; i++)
            {
                string intmp = rdm.Next(1, 999).ToString();

                if (intmp.Length == 1)
                {
                    K += "-00" + intmp;
                    continue;
                }
                else if (intmp.Length == 2)
                {
                    K += "-0" + intmp;
                    continue;
                }
                else
                {
                    K += "-" + intmp;
                    continue;
                }
            }
            K = K.Remove(0, 1);
            return K;
        }
    }
}